using System.Collections.Generic;
using Gameplay.PVE.Utils;
using UnityEngine;
using Yoozoo.Libs;

namespace Gameplay.PVE
{
    public class VehicleRoadPath : UnitRoadPath
    {
        private List<Vector3> pathList;
        private int nextIndex;
        private float idleStartTime;
        private float idleTime;
        private bool isWaiting = false;
        private bool isMoving = false;
        private bool isLeaving = false;

        private float accelerateBrake = -10 * PveUtils.globalRatio;
        private float accelerate = 2.5f * PveUtils.globalRatio;
        private float maxSpeed = 10 * PveUtils.globalRatio;
        private float targetSpeed = 5 * PveUtils.globalRatio;
        private float currentSpeed = 0;
        
        
        protected override void Reset()
        {
            isWaiting = false;
            isMoving = false;
            isLeaving = false;
            pathList = null;
        }
        
        public override void Update()
        {
            base.Update();
            if (idleTime != 0)
            {
                currentSpeed = 0;
                if (TimeManager.logicTime - idleStartTime > idleTime)
                {
                    idleTime = 0;
                    isMoving = true;
                }
                position = unit.Data.position;
            }
            else
            {
                UpdateSpeed();
                UpdateRoadPath();
            }
           

            if (position != unit.Data.position)
            {
                unit.Data.SetTargetForward(position - unit.Data.position);
            }
            
        }

        public override void UpdateData()
        {
            if (isWaiting)
            {
                return;
            }

            if (isMoving)
            {
                return;
            }

            if (pathList == null)
            {
                actionName = "Walk";
                actionSpeed = 0.7f;
                pathList = PveManager.Instance.GetVehiclePath(unit.Data.stage);
                if (pathList.Count == 0)
                {
                    //Debug.LogError("null");
                    return;
                }
                StartRoadPath();
            }
            isMoving = true;
            if (idleTime == 0)
            {
                currentSpeed = 0;
                idleTime = Random.Range(0.5f, 3f);
                idleStartTime = TimeManager.logicTime;
            }
        }

        public override void OnTransmit(ETransmitType type, BaseTransmitArg arg)
        {
            base.OnTransmit(type, arg);
            if (type == ETransmitType.Wait)
            {
                if (isWaiting)
                {
                    return;
                }

                targetSpeed = 0;
                isWaiting = true;
            }
            else if (type == ETransmitType.VehicleAction)
            {
                isWaiting = false;
                targetSpeed = maxSpeed;
                UpdateData();
            }
        }

        private void StartRoadPath()
        {
            //添第一段路
            var dir = (pathList[0] - pathList[1]).normalized;
            pathList.Insert(0,dir * 10 + pathList[0]);
            unit.Data.position = pathList[0];
            unit.Data.SetTargetForward(pathList[1] - pathList[0]);
            unit.Data.forward = pathList[1] - pathList[0];
            //添加最后一段路
            dir = (pathList[pathList.Count - 1] - pathList[pathList.Count - 2]).normalized;
            pathList.Add(dir * 10 + pathList[pathList.Count - 1]);
            nextIndex = 0;
            ToNextPoint();
        }
        
        private void UpdateRoadPath()
        {
            if (isWaiting)
            {
                return;
            }
            if (pathList.Count > nextIndex )
            {
                if (nextIndex > 0)
                {
                    Vector3 targetPosition = pathList[nextIndex];
                    float speed = currentSpeed * Time.deltaTime;
                    if (Vector3.Distance(targetPosition, position) < speed)
                    {
                        ToNextPoint();
                    }
                    else
                    {
                        position = position + speed * (targetPosition - position).normalized;
                    }
                }
                else
                {
                    ToNextPoint();
                }
            }
        }

        private void UpdateSpeed()
        {
            float diff = targetSpeed - currentSpeed;
            float accelerate = diff > 0 ? this.accelerate * Time.deltaTime : this.accelerateBrake * Time.deltaTime;
            if (diff != 0)
            {
                if (Mathf.Abs(diff) < accelerate)
                {
                    currentSpeed = targetSpeed;
                }
                else
                {
                    currentSpeed += accelerate;
                }
            }
        }
        
        private void ToNextPoint()
        {
            position = pathList[nextIndex];
            if (nextIndex < pathList.Count - 1)
            {
                nextIndex++;
            }
            else
            {
                pathList.Clear();
                unit.Dead();
            }
        }
    }
}